<template>
  <div :id="mapId" :style="containerStyle"></div>
</template>

<script setup lang="ts">
import AMapLoader from '@amap/amap-jsapi-loader';

// 自动生成不重复的ID
const generateUniqueId = () => {
  return `amap-container-${Date.now()}`;
};

const mapId = ref(generateUniqueId());

const emit = defineEmits(['updateCoordinates', 'load', 'updateGeojson']);

// 定义props接收父组件传递的样式
const props = defineProps({
  containerStyle: {
    type: String,
    default: () => "width: '100%';height: '400px'"
  }
});

const map = ref(null);
const currentPoint = ref(null);
const marker = ref(null);
const polygon = ref(null);
const polygonEditor = ref(null);
const polyline = ref(null);
const polylineEditor = ref(null);
const geojsonList = ref<[]>([]);

onMounted(() => {
  window._AMapSecurityConfig = {
    securityJsCode: '8fb390e492fa56b86264ea9eea48ea52'
  };

  AMapLoader.load({
    key: '19f9eb46f25e294418a7c499c201e37f',
    version: '2.0',
    plugins: ['AMap.Marker', 'AMap.PolylineEditor', 'AMap.PolygonEditor', 'AMap.GeoJSON']
  })
    .then((AMap) => {
      map.value = new AMap.Map(mapId.value, {
        viewMode: '3D',
        zoom: 13,
        center: [120.536494, 31.179787]
      });

      // 地图加载完成后触发事件
      map.value.on('complete', () => {
        emit('load', map.value);
      });
    })
    .catch((e) => {
      console.error(e);
    });
});

onUnmounted(() => {
  if (map.value) {
    map.value.destroy();
  }
});

const enableDrawPoint = () => {
  // 添加点击事件监听
  map.value.on('click', (e: any) => {
    const lnglat = e.lnglat;

    // 如果已有标记点，先移除
    if (currentPoint.value) {
      map.value.remove(currentPoint.value);
    }

    // 创建新的标记点
    currentPoint.value = new AMap.Marker({
      position: [lnglat.getLng(), lnglat.getLat()],
      anchor: 'bottom-center'
    });

    // 将标记点添加到地图
    map.value.add(currentPoint.value);

    // 向父组件发送坐标信息
    emit('updateCoordinates', {
      longitude: lnglat.getLng(),
      latitude: lnglat.getLat()
    });
  });
};

// 清除标记点
const clearPoint = () => {
  if (currentPoint.value) {
    map.value.remove(currentPoint.value);
    currentPoint.value = null;
  }
};

// 设置标记点
const setPoint = (longitude: number, latitude: number) => {
  if (currentPoint.value) {
    map.value.remove(currentPoint.value);
  }

  currentPoint.value = new AMap.Marker({
    position: [longitude, latitude],
    anchor: 'bottom-center'
  });

  map.value.add(currentPoint.value);
};

const enableDrawMarker = () => {
  map.value.on('click', (e: any) => {
    const lnglat = e.lnglat;

    // 如果已有标记点，先移除
    if (marker.value) {
      map.value.remove(marker.value);
    }

    // 创建新的标记点
    marker.value = new AMap.Marker({
      position: [lnglat.getLng(), lnglat.getLat()],
      anchor: 'bottom-center'
    });

    // 将标记点添加到地图
    map.value.add(marker.value);

    const geometry = marker.value.toGeometry();
    const geometryJSON = {
      'type': 'FeatureCollection',
      'features': [
        {
          'type': 'Feature',
          'geometry': geometry,
          'properties': []
        }
      ]
    };
    emit('updateGeojson', {
      geojson: geometryJSON
    });
  });
};

const disableDrawMarker = () => {
  map.value.clearEvents('click');
};

const clearMarker = () => {
  if (marker.value) {
    map.value.remove(marker.value);
    marker.value = null;
  }
};
const setMarker = (geojson) => {
  marker.value = new AMap.GeoJSON({ geoJSON: geojson });
  map.value.add(marker.value);
};

const enableDrawPolyline = () => {
  //引入折线编辑器插件
  map.value.plugin(['AMap.PolylineEditor'], function () {
    //实例化多边形编辑器，传入地图实例和要进行编辑的多边形实例
    polylineEditor.value = new AMap.PolylineEditor(map.value, polyline.value);
    //开启编辑模式
    polylineEditor.value.open();
  });
};

const disableDrawPolyline = () => {
  if (polylineEditor.value) {
    polylineEditor.value.close();
    polyline.value = polylineEditor.value.getTarget();
    const geometry = polyline.value.toGeometry();
    const geometryJSON = {
      'type': 'FeatureCollection',
      'features': [
        {
          'type': 'Feature',
          'geometry': geometry,
          'properties': []
        }
      ]
    };
    emit('updateGeojson', {
      geojson: geometryJSON
    });
    polylineEditor.value = null;
  }
};

const clearPolyline = () => {
  if (polyline.value) {
    map.value.remove(polyline.value);
    polyline.value = null;
  }
};

const setPolyline = (geojson) => {
  polyline.value = new AMap.GeoJSON({ geoJSON: geojson });
  map.value.add(polyline.value);
};

const enableDrawPolygon = () => {
  //引入多边形编辑器插件
  map.value.plugin(['AMap.PolygonEditor'], function () {
    //实例化多边形编辑器，传入地图实例和要进行编辑的多边形实例
    polygonEditor.value = new AMap.PolygonEditor(map.value, polygon.value);
    //开启编辑模式
    polygonEditor.value.open();
  });
};

const disableDrawPolygon = () => {
  if (polygonEditor.value) {
    polygonEditor.value.close();
    polygon.value = polygonEditor.value.getTarget();
    const geometry = polygon.value.toGeometry();
    const geometryJSON = {
      'type': 'FeatureCollection',
      'features': [
        {
          'type': 'Feature',
          'geometry': geometry,
          'properties': []
        }
      ]
    };
    emit('updateGeojson', {
      geojson: geometryJSON
    });
    polygonEditor.value = null;
  }
};

const clearPolygon = () => {
  if (polygon.value) {
    map.value.remove(polygon.value);
    polygon.value = null;
  }
};

const setPolygon = (geojson) => {
  polygon.value = new AMap.GeoJSON({ geoJSON: geojson });
  map.value.add(polygon.value);
};

const showGeojson = (geojsons: []) => {
  map.value.remove(geojsonList.value);
  geojsonList.value = [];
  for (const item in geojsons) {
    const geo = new AMap.GeoJSON({ geoJSON: item });
    geojsonList.value.push(geo);
    map.value.add(geo);
  }
};

const clearAll = () => {
  map.value.clearMap();
};

// 暴露方法给父组件使用
defineExpose({
  enableDrawMarker,
  disableDrawMarker,
  clearMarker,
  setMarker,
  enableDrawPolyline,
  disableDrawPolyline,
  clearPolyline,
  setPolyline,
  enableDrawPolygon,
  disableDrawPolygon,
  clearPolygon,
  setPolygon,
  clearAll,
  clearPoint,
  setPoint,
  showGeojson,
  enableDrawPoint
});
</script>

<style lang="scss" scoped></style>
